using SharedKernel.Domain;
using SharedKernel.Domain.Events;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using OrderService.Domain.Events;

namespace OrderService.Domain.Models
{
    /// <summary>
    /// 订单实体
    /// </summary>
    public class Order : CreateUpdateDeleteEntity<Guid>
    {
        /// <summary>
        /// 订单编号
        /// </summary>
        public string OrderNumber { get; private set; }

        /// <summary>
        /// 客户ID
        /// </summary>
        public Guid CustomerId { get; private set; }

        /// <summary>
        /// 订单状态
        /// </summary>
        public OrderStatus Status { get; private set; }

        /// <summary>
        /// 订单总金额
        /// </summary>
        public decimal TotalAmount { get; private set; }

        /// <summary>
        /// 配送地址
        /// </summary>
        public string ShippingAddress { get; set; }

        /// <summary>
        /// 手机号码
        /// </summary>
        public string PhoneNumber { get; set; }

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreatedAt { get; set; }

        /// <summary>
        /// 更新时间
        /// </summary>
        public DateTime UpdatedAt { get; set; }

        /// <summary>
        /// 备注
        /// </summary>
        public string Remark { get; set; }

        /// <summary>
        /// 订单商品项
        /// </summary>
        public List<OrderItem> Items { get; private set; } = new();

        // 领域事件相关
        private readonly List<DomainEvent> _domainEvents = new();

        /// <summary>
        /// 领域事件集合
        /// </summary>
        public IReadOnlyCollection<DomainEvent> DomainEvents => new ReadOnlyCollection<DomainEvent>(_domainEvents);

        /// <summary>
        /// 清除领域事件
        /// </summary>
        public void ClearDomainEvents()
        {
            _domainEvents.Clear();
        }

        /// <summary>
        /// 添加领域事件
        /// </summary>
        /// <param name="domainEvent">领域事件</param>
        private void AddDomainEvent(DomainEvent domainEvent)
        {
            _domainEvents.Add(domainEvent);
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="id">订单ID</param>
        /// <param name="orderNumber">订单编号</param>
        /// <param name="customerId">客户ID</param>
        /// <summary>
        /// 公共无参数构造函数，用于ORM框架
        /// </summary>
        public Order() : base(Guid.NewGuid())
        {
            OrderNumber = "";
        }

        /// <summary>
        /// 私有构造函数
        /// </summary>
        /// <param name="id">订单ID</param>
        /// <param name="orderNumber">订单编号</param>
        /// <param name="customerId">客户ID</param>
        private Order(Guid id, string orderNumber, Guid customerId)
            : base(id)
        {
            OrderNumber = orderNumber;
            CustomerId = customerId;
            Status = OrderStatus.PendingPayment;
            TotalAmount = 0;
        }

        /// <summary>
        /// 创建订单
        /// </summary>
        /// <param name="customerId">客户ID</param>
        /// <param name="items">订单项列表</param>
        /// <returns>订单实例</returns>
        public static Order Create(Guid customerId, List<OrderItem> items)
        {
            if (items == null || items.Count == 0)
                throw new ArgumentException("订单项不能为空", nameof(items));

            var orderNumber = GenerateOrderNumber();
            var order = new Order(Guid.NewGuid(), orderNumber, customerId);

            foreach (var item in items)
            {
                order.Items.Add(item);
            }

            order.UpdateTotalAmount();
            order.AddDomainEvent(new OrderCreatedEvent(order));
            return order;
        }

        /// <summary>
        /// 生成订单编号
        /// </summary>
        /// <returns>订单编号</returns>
        private static string GenerateOrderNumber()
        {
            return DateTime.Now.ToString("yyyyMMddHHmmss") + Guid.NewGuid().ToString("N").Substring(0, 6);
        }

        /// <summary>
        /// 添加订单项
        /// </summary>
        /// <param name="productId">商品ID</param>
        /// <param name="productName">商品名称</param>
        /// <param name="unitPrice">单价</param>
        /// <param name="quantity">数量</param>
        public void AddItem(Guid productId, string productName, decimal unitPrice, int quantity)
        {
            if (quantity <= 0)
                throw new ArgumentException("商品数量必须大于0", nameof(quantity));

            if (unitPrice < 0)
                throw new ArgumentException("商品单价不能小于0", nameof(unitPrice));

            var item = OrderItem.Create(productId, productName, unitPrice, quantity);
            Items.Add(item);
            UpdateTotalAmount();
            //MarkAsUpdated();
        }

        /// <summary>
        /// 更新订单状态
        /// </summary>
        /// <param name="status">新状态</param>
        public void UpdateStatus(OrderStatus status)
        {
            Status = status;
            //MarkAsUpdated();
        }

        /// <summary>
        /// 更新订单总金额
        /// </summary>
        private void UpdateTotalAmount()
        {
            TotalAmount = Items.Sum(item => item.LineTotal);
        }

        /// <summary>
        /// 取消订单
        /// </summary>
        public void Cancel()
        {
            if (Status == OrderStatus.Canceled)
                throw new InvalidOperationException("订单已经被取消");

            if (Status == OrderStatus.Shipped || Status == OrderStatus.Completed)
                throw new InvalidOperationException("已发货或已完成的订单不能取消");

            Status = OrderStatus.Canceled;
            //MarkAsUpdated();
            // 可以添加取消订单的领域事件
        }
    }

    /// <summary>
    /// 订单状态
    /// </summary>
    public enum OrderStatus
    {
        /// <summary>
        /// 待付款
        /// </summary>
        PendingPayment,

        /// <summary>
        /// 已付款
        /// </summary>
        Paid,

        /// <summary>
        /// 已发货
        /// </summary>
        Shipped,

        /// <summary>
        /// 已完成
        /// </summary>
        Completed,

        /// <summary>
        /// 已取消
        /// </summary>
        Canceled
    }
}